package com.guangfeng.yql.mysql.engine;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.guangfeng.yql.comm.util.ModuleUtils;
import com.guangfeng.yql.comm.util.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.Map;

@Slf4j
public final class AlibabaVelocityTemplateEngine extends VelocityTemplateEngine {
    private Boolean isFirst = true;

    /**
     * 渲染对象 MAP 信息
     *
     * @param config    配置信息
     * @param tableInfo 表信息对象
     * @return ignore
     */
    @Override
    public Map<String, Object> getObjectMap(ConfigBuilder config, TableInfo tableInfo) {
        return super.getObjectMap(config, tableInfo);
    }

    @Override
    protected String getPathInfo(OutputFile outputFile) {
        String info = super.getPathInfo(outputFile);
        String root = getConfigBuilder().getGlobalConfig().getOutputDir();
        return getUrl(info, root, ModuleUtils.getModuleNameParserPage(info));
    }

    public String getUrl(String info, String root, String moduleName) {
        if (moduleName == null) {
            return info;
        }
        return info.replace(root, root + moduleName + "\\src\\main\\java\\");
    }

    /**
     * 输出文件
     *
     * @param file         文件
     * @param objectMap    渲染信息
     * @param templatePath 模板路径
     * @since 3.5.0
     */

    @Override
    protected void outputFile(File file, Map<String, Object> objectMap, String templatePath) {
        if (templatePath.startsWith("/") && templatePath.contains("entity.java.vm")) {
            return;
        }
        firstFormat(objectMap);
        log.info(" file : {} templatePath: {}", file, templatePath);
        log.info(JSONUtil.toJsonStr(objectMap));
        super.outputFile(fileChange(file), objectMap, templatePath);
    }

    public Map<String, Object> packageMapChange(Map<String, Object> objectMap) {
        String jsonStr = JSONUtil.toJsonStr(objectMap.get("package"));
        Map<String, Object> map = JSONUtil.parseObj(jsonStr);
        objectMap.put("package", map);
        return map;
    }

    public File fileChange(File file) {
        if (file.getName().endsWith(".java") || file.getName().endsWith(".xml")) {
            return file;
        }
        String fileName = file.getName();
        File parentFile = file.getParentFile();
        String parentFileName = parentFile.getName();
        return new File(parentFile.getParent() + "\\" + StringUtils.toCamelCase(StringUtils.toUnderScoreCase(fileName)) + "\\" + parentFileName + fileName + ".java");
    }

    public void entityChange(Map<String, Object> objectMap, String name) {
        String entity = objectMap.get("entity").toString();
        objectMap.put("entity" + name, entity + name);
        objectMap.put("entity" + name + "Name", StringUtils.toCamelCase(StringUtils.toUnderScoreCase(entity + name)));
        Map<String, Object> map = (Map<String, Object>) objectMap.get("package");
        map.put("Entity" + name, map.get("Entity").toString() + "." + StringUtils.toCamelCase(StringUtils.toUnderScoreCase(name)));
    }

    public void firstFormat(Map<String, Object> objectMap) {
        synchronized (Object.class) {
            if (isFirst) {
                isFirst = false;
            } else {
                return;
            }
        }
        packageMapChange(objectMap);
        entityChange(objectMap, "Po");
        entityChange(objectMap, "Dto");
        entityChange(objectMap, "Vo");
        String entity = objectMap.get("entity").toString();
        objectMap.put("entityName", StringUtils.toCamelCase(StringUtils.toUnderScoreCase(entity)));
        Map<String, Object> map = (Map<String, Object>) objectMap.get("package");
        map.put("Entity", map.get("Entity") + ".po");

    }
}
